import { BufferGeometry,Line, LineLoop, CatmullRomCurve3, DoubleSide, Group, Plane, Vector3, SphereGeometry, MeshBasicMaterial, Mesh, MathUtils, BoxGeometry, TextureLoader, RepeatWrapping, Box3, PlaneGeometry, LineBasicMaterial } from 'three'
import { DDSLoader } from 'three/examples/jsm/loaders/DDSLoader'
import * as TWEEN from 'three/examples/jsm/libs/tween.module.js'
import { InstancedFlow } from 'three/examples/jsm/modifiers/CurveModifier.js';

export default class InitAnimation {
    constructor(initThree) {
        this.scene = initThree.scene;
        this.camera = initThree.camera;
        this.controls = initThree.controls;
        this.meshGroup = new Group();
        this.meshGroup.name = '动画组';
        this.scene.add(this.meshGroup)
        this.tweenData = []
        this.jianyoutext = new TextureLoader().load('./texture/jiantou.png')
        this.jianyoutext.wrapS = this.jianyoutext.wrapT = RepeatWrapping;
        this.jianyoutext.repeat.set(4, 10);
        this.jianyoutext2 = new TextureLoader().load('./texture/jiantou1.png')
        this.jianyoutext2.wrapS = this.jianyoutext2.wrapT = RepeatWrapping;
        this.jianyoutext2.repeat.set(4, 10);
        this.tweenjiantou = new TWEEN.Tween(this.jianyoutext.offset).to({
            y: -1
        })
        this.tweenjiantou2 = new TWEEN.Tween(this.jianyoutext2.offset).to({
            y: -1
        })
        this.tweenjiantou.repeat(Infinity);
        this.tweenjiantou.start();
        this.tweenjiantou2.repeat(Infinity);
        this.tweenjiantou2.start();
        this.allGroup = new Group()
        this.allGroup.name = '所有履带'
        this.scene.add(this.allGroup)
    }

    addBubble(model, height, count) {
        let meshlist = []
        model.traverse((child) => {
            if (child.isMesh && child.name.includes("球体")) {
                child.visible = false;
                meshlist.push(child)
            }
        })
        if (!meshlist) return
        let grouplist = new Group()
        grouplist.name = model.name + '-气泡群'
        let position = new Vector3();
        meshlist[0].getWorldPosition(position);
        const planelist = [new Plane(new Vector3(0, -1, 0), position.y + height), new Plane(new Vector3(0, 1, 0), -position.y)];
        const spheregeo = new SphereGeometry(0.2)
        let ddsLoader = new DDSLoader()
        let texture = ddsLoader.load('./texture/qipao2.dds');
        const spheremater = new MeshBasicMaterial({
            map: texture,
            transparent: true,
            opacity: 1,
            clippingPlanes: planelist
        })
        const sphere = new Mesh(spheregeo, spheremater)
        sphere.name = '气泡';
        let qipaogroup = new Group();
        qipaogroup.name = '气泡组'
        for (let i = 0; i < count; i++) {
            let positionrandom = new Vector3((Math.random() - 0.5) * 1, Math.random() * height * 2, (Math.random() - 0.5) * 1);
            const clonesphere = sphere.clone();
            clonesphere.position.set(positionrandom.x, positionrandom.y, positionrandom.z)
            qipaogroup.add(clonesphere)
        }
        for (let i of meshlist) {
            let zuposition = new Vector3();
            i.getWorldPosition(zuposition);
            const clonezu = qipaogroup.clone()
            clonezu.position.set(zuposition.x, zuposition.y - height, zuposition.z);
            grouplist.add(clonezu)
        }
        const grouptween = new TWEEN.Tween(grouplist).to({
            position: {
                y: height
            }
        }, 1000)
        grouptween.repeat(Infinity);
        grouptween.start();
        grouplist.visible = false;
        console.log(grouplist)
        this.meshGroup.add(grouplist)
    }

    // FlowingWater(model, zu, name) {
    //     let waterlist = []
    //     model.traverse((child) => {
    //         if (child.isMesh && child.name.includes(name)) {
    //             let objPosition = new Vector3();
    //             child.getWorldPosition(objPosition);
    //             child.visible = false;
    //             waterlist.push({
    //                 mesh: child,
    //                 position: objPosition
    //             })
    //         }
    //     })
    //     if (!waterlist) return
    //     const textureloader = new TextureLoader();
    //     const texture = textureloader.load("./texture/water1.jpg");
    //     texture.wrapS = texture.wrapT = RepeatWrapping;
    //     const mat = new MeshBasicMaterial({
    //         map: texture,
    //         transparent: true,
    //         opacity: 0.6,
    //         side: DoubleSide
    //     })
    //     let group = new Group();
    //     group.name = model.name + '-' + name;
    //     let tweenlist = []
    //     for (let i of waterlist) {
    //         let box = new Box3().setFromObject(i.mesh);
    //         let dur = i.mesh.name.substr(i.mesh.name.length - 1, 1);
    //         let movez = 0
    //         if (i.mesh.name.includes('-')) {
    //             movez = (box.max[dur] - box.min[dur]) / 2
    //         } else if (i.mesh.name.includes('+')) {
    //             movez = -(box.max[dur] - box.min[dur]) / 2
    //         }
    //         let center = new Vector3();
    //         box.getCenter(center);
    //         const watergeo = new BoxGeometry((box.max.x - box.min.x), (box.max.y - box.min.y), (box.max.z - box.min.z));
    //         let water = new Mesh(watergeo, mat)
    //         water.name = i.mesh.name
    //         water.translateX(i.position.x)
    //         water.translateY(i.position.y)
    //         water.translateZ(i.position.z)
    //         water.position[dur] = water.position[dur] + movez
    //         water.scale[dur] = 0;
    //         let tween = new TWEEN.Tween(water).to({
    //             position: {
    //                 [dur]: i.position[dur]
    //             },
    //             scale: {
    //                 [dur]: 1
    //             }
    //         }, 3000).onComplete(() => {
    //             if (!i.mesh.name.includes('-')) {
    //                 i.mesh.name = model.name + '-' + i.mesh.name
    //             }
    //             if (model.name != '加药间') {
    //                 this.initJianTou.addjiantou(i.mesh, './texture/jiantou2.png')
    //             }
    //         })
    //         let num = i.mesh.name.substr(3, 2)
    //         tweenlist[parseInt(num) - 1] = tween
    //         group.add(water)
    //     }
    //     for (let j = 0; j < tweenlist.length - 1; j++) {
    //         if ((j + 1) % zu == 0) {
    //             let num = (j + 1) / zu;
    //             tweenlist[(num - 1) * zu].onStart(() => {
    //                 tweenlist[j + 1]?.start();
    //             })
    //             continue
    //         }
    //         tweenlist[j].chain(tweenlist[j + 1])
    //     }
    //     this.tweenData.push({
    //         name: model.name + '-' + name,
    //         tween: tweenlist
    //     })
    //     this.meshGroup.add(group)
    // }

    addPiping(model, name) {
        let mat = new MeshBasicMaterial({
            map: this.jianyoutext,
            opacity: 1,
            transparent: true
        })
        if (name == '气管' || name == '气流走向') {
            mat.map = this.jianyoutext2
        }
        model.traverse((child) => {
            if (child.isMesh && child.name.includes(name)) {
                child.material = mat
            }
        })

    }

    SelfRotation(model) {
        model.traverse((child) => {
            if (child.isMesh && child.name.includes('Archmodels')) {
                let tween = new TWEEN.Tween(child.rotation).to({
                    y: Math.PI * 2
                }, 2000).onComplete(() => {
                    child.rotation.y = 0;
                })
                tween.repeat(Infinity)
                tween.start();
            }
        })
    }

    SetRoute(model, name) {
        let arr = [];
        let chushi = new TWEEN.Tween(this.camera).to({
            position: {
                x: -150,
                y: 150,
                z: 150
            }
        }, 4000).onComplete(() => {
            this.controls.target = new Vector3(0, 0, 0);
        })
        model.traverse((child) => {
            if (child.isMesh && child.name.includes(name)) {
                let box = new Box3().setFromObject(child);
                let center = new Vector3();
                box.getCenter(center);
                let tween = new TWEEN.Tween(this.camera.position).to({
                    x: center.x,
                    y: center.y + 100,
                    z: center.z + 20
                }, 4000).onStart(() => {
                    new TWEEN.Tween(this.controls.target).to({
                        x: center.x,
                        y: center.y,
                        z: center.z
                    }, 4000).start()
                });
                let num = parseInt(child.name.substr(2, 2)) - 1
                arr[num] = tween
            }
        })
        arr[arr.length - 1].chain(chushi)
        for (let i = 0; i < arr.length - 1; i++) {
            if (arr[i + 1]) {
                arr[i].chain(arr[i + 1])
            }
        }
        return arr
    }

    setTrackAnimation(line, mesh,position) {
        let posArray = line.geometry.attributes.position.array
        let linePos = this.getThreePosition(posArray)
        for(let i=0;i<linePos.length;i++){
            linePos[i][0]=linePos[i][0]+position.x
            linePos[i][1]=linePos[i][1]+position.y
            linePos[i][2]=linePos[i][2]+position.z
        }
        let curvePoint = []
        linePos.forEach((item) => {
            curvePoint.push(new Vector3(item[0], item[1], item[2]))
        })
        let curveObj = this.getCurveMesh(curvePoint)
        let CountGo = 48
        let inflow = new InstancedFlow(CountGo, curveObj[0].points.length, mesh.geometry, mesh.material);
        for (let i = 0; i < curveObj[0].points.length; i++) {
            inflow.updateCurve(i, curveObj[0])
            this.allGroup.add(inflow.object3D)
        }
        for (let i = 0; i < CountGo; i++) {
            // inflow.updateCurve(i,curveObj[0]);
            // allGroup.add(inflow.object3D)
            const curveIndex = i % curveObj[0].points.length
            inflow.setCurve(i, curveIndex);
            inflow.moveIndividualAlongCurve(i, i * 1 / CountGo);
        }
        setInterval(() => {
            inflow.moveAlongCurve(0.001)
        }, 40)
    }

    getBox(size) {
        const geometry = new BoxGeometry(size * 2, size * 5, size);
        const material = new MeshBasicMaterial({ color: 0x00ff00 });
        const cube = new Mesh(geometry, material);
        return cube
    }

    getThreePosition(data) {
        let groupedData = []
        for (let i = 0; i < data.length; i += 3) {
            if (i + 2 < data.length) {
                groupedData.push(data.slice(i, i + 3));
            } else {
                groupedData.push(data.slice(i));
            }
        }
        return groupedData;
    }

    getCurveMesh(arrP) {
        const curve = new CatmullRomCurve3(arrP);
        const points = curve.getPoints(60);
        const geometry = new BufferGeometry().setFromPoints(points);
        const material = new LineBasicMaterial({ color: 0x00ff00 });
        const curveObject = new Line(geometry, material);
        const curveObj = [curve, curveObject]
        return curveObj
    }


    setgebanAnimation(obj){
        const tween1 =  new TWEEN.Tween(obj.position).to({
           y:20
        }, 4000)
        const tween2 =  new TWEEN.Tween(obj.position).to({
           y:0
        }, 4000)
        tween1.chain(tween2)
        tween2.chain(tween1)
        tween1.start()
    }


    setZhuaDouAnimation(obj) {
        const tween1 = new TWEEN.Tween(obj.position).to({
            x: 28,
        }, 4000)
        const tween11 = new TWEEN.Tween(obj.position).to({
            x: 0,
        }, 4000)

        let obj1 = obj.getObjectByName('抓手1')
        const tween2 = new TWEEN.Tween(obj1.rotation).to({
            x: 0.3,
        }, 4000)
        const tween22 = new TWEEN.Tween(obj1.rotation).to({
            x: 0,
        }, 4000)

        let obj2 = obj.getObjectByName('抓手2')
        const tween3 = new TWEEN.Tween(obj2.rotation).to({
            x: -0.3,
        }, 4000)
        const tween33 = new TWEEN.Tween(obj2.rotation).to({
            x: 0,
        }, 4000)

        let obj3 = obj.getObjectByName('伸缩杆')
        const tween4 = new TWEEN.Tween(obj3).to({
            position: {
                y: -1435
            },
            scale: {
                y: 13.6
            }
        }, 2000)
        const tween44 = new TWEEN.Tween(obj3).to({
            position: {
                y: 0
            },
            scale: {
                y: 1
            }
        }, 2000)

        let obj4 = obj.getObjectByName('横杆')
        const tween5 = new TWEEN.Tween(obj4.position).to({
            y: -90
        }, 2000)
        const tween55 = new TWEEN.Tween(obj4.position).to({
            y: 0
        }, 2000)

        let obj5 = obj.getObjectByName('抓手组')
        const tween6 = new TWEEN.Tween(obj5.position).to({
            y: -90
        }, 2000)
        const tween66 = new TWEEN.Tween(obj5.position).to({
            y: 0
        }, 2000)

        tween2.onStart(() => {
            tween3.start()
        }).onComplete(() => {
            tween1.start()
        })

        tween1.onComplete(() => {
            tween4.start()
            tween5.start()
            tween6.start()
        })

        tween6.onComplete(() => {
            tween22.start()
            tween33.start()
        })

        tween33.onComplete(() => {
            tween44.start()
            tween55.start()
            tween66.start()
        })

        tween66.onComplete(() => {
            tween11.start()
        })

        tween11.chain(tween2)

        tween2.start()
    }
}